package com.plian.system.controller.transfer;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.config.AppKeySign;
import com.plian.system.dao.sys.file.FileDao;
import com.plian.system.dto.pm.property.PropertyFileDTO;
import com.plian.system.dto.pm.property.PropertyInfoDTO;
import com.plian.system.dto.transfer.DataPlatSign;
import com.plian.system.entity.fr.bank.BankKey;
import com.plian.system.entity.pm.property.*;
import com.plian.system.model.R;
import com.plian.system.model.token.PassToken;
import com.plian.system.service.fr.bank.IBankKeyService;
import com.plian.system.service.pm.property.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: gangan
 * @create: 2021-05-20 14:24
 */
@RestController
@RequestMapping(value = "api/propertydatatransfer")
@Api(value = "产权数据对接", tags = "产权数据对接")
@Slf4j
public class PropertyDataTransferController {

    @Autowired
    private IPropertyService propertyService;

    @Autowired
    private IPropertyBasicsService propertyBasicsService;

    @Autowired
    private IPropertyRecordService propertyRecordService;

    @Autowired
    private IPropertyChangeService propertyChangeService;

    @Autowired
    private IPropertyOutService propertyOutService;

    @Autowired
    private IPropertyFileService propertyFileService;

    @Autowired
    private IBankKeyService bankKeyService;

    @Autowired
    private IContributorBasicsService contributorBasicsService;

    @Autowired
    private IPartnerSituationBasicsService partnerSituationBasicsService;

    @Autowired
    private IPartnerOutboundBasicsService outboundBasicsService;

    @Autowired
    private IShareholdingBasicsService shareholdingBasicsService;

    @Autowired
    FileDao fileDao;

    @PostMapping(value = "/save/registerList")
    @ApiOperation(value = "国资委 产权登记数据", notes = "传入propertyList、contributorList、shareholdingList、partnerOutboundList、partnerSituationList ")
    public R registerList(@RequestBody PropertyInfoDTO propertyInfoDTO){
        String message = propertyService.checkList(propertyInfoDTO, TokenUtil.getCompetentOrganization());
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyService.saveList(propertyInfoDTO));
    }

    @PostMapping(value = "/save/changeList")
    @ApiOperation(value = "国资委 产权变更数据", notes = "传入propertyChangeList、contributorChangeList、shareholdingChangeList、partnerOutboundChangeList、partnerSituationChangeList ")
    public R changeList(@RequestBody PropertyInfoDTO propertyInfoDTO){
        String message = propertyChangeService.checkList(propertyInfoDTO, TokenUtil.getCompetentOrganization());
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyChangeService.saveList(propertyInfoDTO));
    }

    @PostMapping(value = "/save/outList")
    @ApiOperation(value = "国资委 产权注销数据", notes = "传入propertyOutList")
    public R outList(@RequestBody PropertyInfoDTO propertyInfoDTO){
        String message = propertyOutService.checkList(propertyInfoDTO, TokenUtil.getCompetentOrganization());
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyOutService.saveList(propertyInfoDTO));
    }

    @PostMapping(value = "/save/file")
    @ApiOperation(value = "国资委 附件", notes = "覆盖原有数据 传入文件、文件信息json")
    public R file(@RequestParam(value = "files") List<MultipartFile> files, @RequestParam String fileInfo){
        List<PropertyFileDTO> propertyFileDTOS = JSON.parseArray(fileInfo, PropertyFileDTO.class);
        String message = propertyFileService.check(propertyFileDTOS, TokenUtil.getCompetentOrganization());
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyFileService.save(files, propertyFileDTOS));
    }

    @PostMapping(value = "/unit/save/registerList")
    @ApiOperation(value = "集团 产权登记数据", notes = "传入propertyList、contributorList、shareholdingList、partnerOutboundList、partnerSituationList ")
    public R unitRegisterList(@RequestBody PropertyInfoDTO propertyInfoDTO){
        String message = propertyService.unitCheckList(propertyInfoDTO, TokenUtil.getCompetentOrganization());
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyService.unitSaveList(propertyInfoDTO));
    }

    @PostMapping(value = "/unit/save/changeList")
    @ApiOperation(value = "集团 产权变更数据", notes = "传入propertyChangeList、contributorChangeList、shareholdingChangeList、partnerOutboundChangeList、partnerSituationChangeList ")
    public R unitChangeList(@RequestBody PropertyInfoDTO propertyInfoDTO){
        String message = propertyChangeService.unitCheckList(propertyInfoDTO, TokenUtil.getCompetentOrganization());
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyChangeService.unitSaveList(propertyInfoDTO));
    }

    @PostMapping(value = "/unit/save/outList")
    @ApiOperation(value = "集团 产权注销数据", notes = "传入propertyOutList")
    public R unitOutList(@RequestBody PropertyInfoDTO propertyInfoDTO){
        String message = propertyOutService.unitCheckList(propertyInfoDTO, TokenUtil.getCompetentOrganization());
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyOutService.unitSaveList(propertyInfoDTO));
    }

    @PostMapping(value = "/unit/save/file")
    @ApiOperation(value = "集团 附件", notes = "覆盖原有数据 传入文件、文件信息json")
    public R unitFile(@RequestParam(value = "files") List<MultipartFile> files, @RequestParam String fileInfo){
        List<PropertyFileDTO> propertyFileDTOS = JSON.parseArray(fileInfo, PropertyFileDTO.class);
        String message = propertyFileService.unitCheck(propertyFileDTOS);
        if (StringUtil.isNotBlank(message)){
            return R.fail(message);
        }
        return R.status(propertyFileService.save(files, propertyFileDTOS));
    }

    /**
     * 提供时间段内的数据接口
     * @param dataPlatSign
     */
    @PostMapping(value = "/property-time")
    @PassToken
    @AppKeySign
    public R<List<PropertyBasics>> propertyByTime(@RequestBody DataPlatSign dataPlatSign){
        log.debug("toklen:" + dataPlatSign.getToken());
        String appId = dataPlatSign.getAppId();
        BankKey bankKey = bankKeyService.getOne(Wrappers.<BankKey>lambdaQuery().eq(BankKey::getAppId, appId));
        String topGroupId = bankKey.getTopGroupId();
        PropertyBasics one = propertyBasicsService.getOne(new LambdaQueryWrapper<PropertyBasics>().eq(PropertyBasics::getOrgId, topGroupId));
        List<PropertyBasics> allChild = propertyBasicsService.getAllChild(one.getId());
        if (Optional.ofNullable(dataPlatSign.getEndTime()).isPresent()){
            allChild = allChild.stream().filter(pro -> Optional.ofNullable(pro.getUpdateTime()).isPresent() &&
                    (dataPlatSign.getStartTime().compareTo(pro.getUpdateTime()) < 1 && dataPlatSign.getEndTime().compareTo(pro.getUpdateTime()) > -1)).collect(Collectors.toList());
        }

        setPropertyDetail(allChild);
        return R.data(allChild);
    }

    /**
     * @Author: Take-off
     * @Description: //TODO 产权放入子信息
     * @Date: 3:04 PM 2022/12/6
     * @Param: [propertyBasics]
     * @return: void
     **/
    private void setPropertyDetail(List<PropertyBasics> propertyBasics){
        if (CollectionUtil.isNotEmpty(propertyBasics)){
            List<String> proIds = propertyBasics.stream().map(PropertyBasics::getId).collect(Collectors.toList());
            //出资人情况
            List<ContributorBasics> contributors = contributorBasicsService.list(
                    new LambdaQueryWrapper<ContributorBasics>().in(ContributorBasics::getPropertyId, proIds).orderByAsc(ContributorBasics::getOrderNum));
            if (CollectionUtil.isNotEmpty(contributors)){
                Map<String, List<ContributorBasics>> childMap = contributors.stream().collect(Collectors.groupingBy(ContributorBasics::getPropertyId));
                propertyBasics.forEach(basic ->{
                    basic.setContributorBasicsList(childMap.get(basic.getId()));
                });
            }
            //单位性质为境外，查询境外控股人
            List<ShareholdingBasics> shareholdings = shareholdingBasicsService.list(
                    new LambdaQueryWrapper<ShareholdingBasics>().in(ShareholdingBasics::getPropertyId, proIds).orderByAsc(ShareholdingBasics::getOrderNum));
            if (CollectionUtil.isNotEmpty(shareholdings)){
                Map<String, List<ShareholdingBasics>> childMap = shareholdings.stream().collect(Collectors.groupingBy(ShareholdingBasics::getPropertyId));
                propertyBasics.forEach(basic ->{
                    basic.setShareholdingBasicsList(childMap.get(basic.getId()));
                });
            }
            //单位性质为合伙人，查询合伙人登记-情况
            List<PartnerSituationBasics> partnerSituations = partnerSituationBasicsService.list(
                    new LambdaQueryWrapper<PartnerSituationBasics>().in(PartnerSituationBasics::getPropertyId, proIds).orderByAsc(PartnerSituationBasics::getSortCode));
            if (CollectionUtil.isNotEmpty(partnerSituations)){
                Map<String, List<PartnerSituationBasics>> childMap = partnerSituations.stream().collect(Collectors.groupingBy(PartnerSituationBasics::getPropertyId));
                propertyBasics.forEach(basic ->{
                    basic.setSituationBasicsList(childMap.get(basic.getId()));
                });
            }
            //合伙人对外投资情况
            List<PartnerOutboundBasics> partnerOutbounds = outboundBasicsService.list(
                    new LambdaQueryWrapper<PartnerOutboundBasics>().in(PartnerOutboundBasics::getPropertyId, proIds).orderByAsc(PartnerOutboundBasics::getSortCode));
            if (CollectionUtil.isNotEmpty(partnerOutbounds)){
                Map<String, List<PartnerOutboundBasics>> childMap = partnerOutbounds.stream().collect(Collectors.groupingBy(PartnerOutboundBasics::getPropertyId));
                propertyBasics.forEach(basic ->{
                    basic.setOutboundBasicsList(childMap.get(basic.getId()));
                });
            }

            fileList(propertyBasics);
        }
    }

    /**
     * @Author: Take-off
     * @Description: //TODO 附件情况
     * @Date: 3:13 PM 2022/12/6
     * @Param: [propertyBasics]
     * @return: void
     **/
    private void fileList(List<PropertyBasics> propertyBasics){
        if (CollectionUtil.isNotEmpty(propertyBasics)) {
            List<String> recordIds = new ArrayList<>();
            Map<String, String> map = new HashMap<>();
            List<PropertyRecord> recordList = propertyRecordService.list(new LambdaQueryWrapper<PropertyRecord>().eq(PropertyRecord::getStatus, 3)
                    .in(PropertyRecord::getInitialId, propertyBasics.stream().map(PropertyBasics::getId).collect(Collectors.toList())));

            //record表
            propertyBasics.forEach(basic ->{
                List<PropertyRecord> records = recordList.stream().filter(record -> record.getInitialId().equals(basic.getId())).sorted(Comparator.comparing(PropertyRecord::getUpdateTime).reversed()).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(records)){
                    String recordId = records.get(0).getId();
                    recordIds.add(recordId);
                    map.put(basic.getId(),recordId);
                }else {
                    recordIds.add(basic.getId());
                    map.put(basic.getId(),basic.getId());
                }
            });
            try {
                List<PageData> files = fileDao.findbyParentIds(recordIds);
                Map<String, List<PageData>> childMap = files.stream().collect(Collectors.groupingBy(file -> file.getString("parentId")));
                propertyBasics.forEach(basic ->{
                    String recordId = map.get(basic.getId());
                    if (StringUtil.isNotBlank(recordId)){
                        basic.setFiles(childMap.get(recordId));
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
